package com.xncoding.pos.config.norepeat;

import com.xncoding.pos.config.HttpRequestUtil;
import com.xncoding.pos.config.R;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

@Aspect
@Component
@Order(10)
public class RepeatSubmitAspect {

    private static final Logger LOGGER = LoggerFactory.getLogger(RepeatSubmitAspect.class);

    @Resource
    private JedisLock jedisLock;

    @Resource
    private HttpServletRequest request;

    @Pointcut("@annotation(noRepeatSubmit)")
    public void pointCut(NoRepeatSubmit noRepeatSubmit) {
    }

    @Around("pointCut(noRepeatSubmit)")
    public Object around(ProceedingJoinPoint pjp, NoRepeatSubmit noRepeatSubmit) throws Throwable {
        int lockSeconds = noRepeatSubmit.lockTime();
        Assert.notNull(request, "request can not null");
        Object userIdObj=request.getAttribute("USER_ID");
        String userId;
        if(userIdObj == null || !StringUtils.hasText(userIdObj.toString())){
            userId= HttpRequestUtil.getRemoteIp(request);
        }else {
            userId=userIdObj.toString();
        }
        StringBuilder key= new StringBuilder(userId);
        key.append(request.getServletPath());

        String clientId = System.currentTimeMillis()+"";
        System.out.println("lock key="+key);

        boolean isSuccess = jedisLock.setLock(key.toString(),clientId,lockSeconds);
        if (isSuccess) {
            // 获取锁成功
            Object result;
            try {
                // 执行进程
                result = pjp.proceed();
            } finally {
                // 解锁
                if(noRepeatSubmit.autoUnLock()) {
                    isSuccess = jedisLock.releaseLock(key.toString(), clientId);
                }
            }
            return result;
        } else {
            // 获取锁失败，认为是重复提交的请求
            LOGGER.info("tryLock fail, key = [{}]", key.toString());
            return R.fail("系统正在处理，请不要重复操作！");
        }

    }

    private String getKey(String token, String path) {
        return token + path;
    }
}
